from flask import Flask, render_template, url_for, request, session, redirect,jsonify,Response
from flask import flash
import json

from nltk.stem.porter import PorterStemmer
from nltk.parse import stanford
from nltk.corpus import stopwords
from nltk.tokenize import sent_tokenize,word_tokenize
from nltk.corpus import wordnet
from nltk import word_tokenize, pos_tag
from nltk.stem import WordNetLemmatizer

from flask_pymongo import PyMongo
import bcrypt
import time as time

from sentence import Sentence

from gtts import gTTS
from io import BytesIO

import re,random

def tts_mp3(text):
	res=re.split(r'\,',text)
	datas=b''
	for sentence in res:
	    fp = BytesIO()
	    tts = gTTS(sentence, 'en')
	    
	    tts.write_to_fp(fp)
	    #tts.save(fp)
	    datas=datas+fp.getvalue()
	    #print(datas)
	    fp.close()
	return datas



app = Flask(__name__)


app.config['MONGO_URI'] = 'mongodb://127.0.0.1:27017/vocavola'


mongo = PyMongo(app)

@app.route('/')
def index():
	users = mongo.db.users


	if 'username' in session:
		if not ('user_level' in session):
			return render_template('level.html',username =session['username'])
		else:
			word_index=session['user_level']
			route_cur ='learnmode'
			#print("route_cur:",route_cur)
			return redirect(url_for(route_cur))

	return render_template('index.html')


@app.route('/level',methods = ['POST', 'GET'])

def level():
	try:

		user_level=session
	except:
		return  redirect(url_for('index'))
	try:
		yourlevel=int(session['user_level'])
		yourlevel=int(yourlevel*0.01)
	except:
		yourlevel=60
	return render_template('level.html',username =session['username'],yourlevel=yourlevel)


@app.route('/result',methods = ['POST', 'GET'])
def result():
	users = mongo.db.users
	words = mongo.db.vocawords
	fs_files =mongo.db.fs.files
	fs_chunks = mongo.db.fs.chunks	

	yourlevel = int(request.form['yourlevel'])

	user_level= yourlevel*100
	user_level=str(user_level)

	users.update_one({'name':session['username']},{"$set":{'user_level': user_level}})
	users.update_one({'name':session['username']},{"$set":{'user_bag': []}})

	session['user_level']=user_level

	if user_level:
		return redirect(url_for ('learnmode'))
	return redirect(url_for('index'))






	#print(session['username'] )	




@app.route('/login', methods=['POST'])
def login():
	users = mongo.db.users
	login_user = users.find_one({'name' : request.form['username']})

	if login_user:
		#print("login_user!")
		if bcrypt.hashpw(request.form['pass'].encode('utf-8'), login_user['password']) == login_user['password']:
			session['username'] = request.form['username']
			try:
				user_level=login_user.get('user_level')
				session['user_level']=user_level
				
			except:
				user_level="3000" 
			return redirect(url_for('learnmode'))

		else:

			return redirect(url_for('index'))
	else:
		return 'Invalid username/password combination'

@app.route('/register', methods=['POST', 'GET'])
def register():
	if request.method == 'POST':
		users = mongo.db.users
		existing_user = users.find_one({'name' : request.form['username']})

		if existing_user is None:
			hashpass = bcrypt.hashpw(request.form['pass'].encode('utf-8'), bcrypt.gensalt())
			users.insert({'name' : request.form['username'], 'password' : hashpass})
			session['username'] = request.form['username']
			return redirect(url_for('index'))
		
		return 'That username already exists!'

	return render_template('register.html')


@app.route('/learnmode/jq/<word_index>',methods = ['POST', 'GET'])
def jq(word_index):
	users = mongo.db.users
	words = mongo.db.voca_packed
	
	##users.update_one({'name':session['username']},{"$set":{'user_level': str(word_index)}})
	try:
		##user_level=str(word_index)
		word_doc = words.find_one({'word_index':int(word_index)})
		word=word_doc.get('word')
		word_tip=word_doc.get('word_tip')
		word_def=word_doc.get('word_def')
		wordMusic="/wordMusic/"+word_index+".mp3"
	 
		image_a="/wordJpg/"+word_index+"-a.jpg"
		image_b="/wordJpg/"+word_index+"-b.jpg"
		clipart_c="/wordJpg/"+word_index+"-c.jpg"
		clipart_d="/wordJpg/"+word_index+"-d.jpg"
		word_json={'user_level':str(word_index),'word':word,'word_tip':word_tip,'word_def':word_def,
		'wordMusic':wordMusic,'image_a':image_a,'image_b':image_b,
		'clipart_c':clipart_c,'clipart_d':clipart_d}

	except:
		word_json="not found"	
	#print(word_json)	
	return json.dumps(word_json)
@app.route('/learnmode/rm/<word_index>',methods = ['POST', 'GET'])
def rm(word_index):
	try:
		users = mongo.db.users
		words = mongo.db.voca_packed
		session['user_level']=word_index
		users.update_one({'name':session['username']},{"$set":{'user_level': str(word_index)}})	
		res={'result':True}
	except:
		res={'result':False}
	return json.dumps(res)

@app.route('/learnmode/',methods = ['POST', 'GET'])
def learnmode():
	req_type = request.method
	users = mongo.db.users
	words = mongo.db.voca_packed

	try:

		user_level=session['user_level']
	except:
		return  redirect(url_for('index'))

	bag_len='0'


	return render_template('learnmode.html',user_level=user_level,bag_len=bag_len)


@app.route('/bagmode',methods = [ 'GET'])
def bagmode():

	#print('user: ',session['username'])


	return render_template('bagmode.html'
		)


@app.route('/artical_mode',methods = [ 'GET','POST'])
def artical_mode():

	#print('user: ',session['username'])


	return render_template('artical_mode.html'
		)

@app.route('/artical_mode/grade_list/', methods = [ 'POST'])
def artical_mode_grade_list():
	users = mongo.db.users
	words = mongo.db.voca_packed
	##user_posts=mongo.db.user_posts

	username=session['username']
	#print("username:",username)

	#word_index=request.form['word_index']
	input_text=request.form['input_text']
	#print (input_text)



	say=Sentence(input_text)
	say.sent_token()
	input_text=say.get('sent_token')
	#print('input_text:',input_text)

	sentence_list=[]
	#sentence_mp3_list=[]
	my={}




					

	
	for sentence in input_text:
		try:
			my['sentence']=sentence
			#datas=datas+tts_mp3(sentence)
			#my['sentence_mp3']=tts_mp3(sentence)
			#my['sentence_mp3']=b''
			sentence_list.append(my)
			my={}
		except:
			pass
	##users.update_one({'username':username},{"$set":{'for_post_mp3':datas}})
	datas=b''
	for sentence in input_text:
		try:
			#pass
			datas=datas+tts_mp3(sentence)
		except:
			pass	
	try:		
		users.update_one({'name':username},{"$set":{'for_post_mp3':datas}})
		#print('update sucess')
	except:
		print('update failed')

	grade_list=say.grade_text()

	grade_list.sort()
	#print(grade_list[-15:])
	grade_list = list(set(grade_list))


	
	grade_list=[w for w in grade_list if not w ==0]
	grade_list.sort()

	#print(grade_list)
	if len(grade_list)>24:
		grade_list =[w for w in grade_list[-12:] ]
	else:
		grade_list=	[w for w in grade_list[-6:] ]

	#print(grade_list)
	grade_list.reverse()
	res={'grade_list':grade_list}
	#print('res:',res)
	res_json=json.dumps(res)
	return res_json
@app.route('/artical_mode/<articalMusic>', methods = [ 'GET'])
def artical_mode_music(articalMusic):

	users = mongo.db.users
	username=session['username']
	#print('get username:',username)
	datas=b''

	try:
	
		#print('word_music_filename',word_music_filename)
		music_doc = users.find_one({'name':username})
		#print('get music_doc sucess')
		#print (music_doc)

		datas=music_doc.get('for_post_mp3')
		#print ('gets datas:',datas)
	except:
		print ('gets datas failed')

	
	response= Response(datas, mimetype="audio/mpeg")

	response.headers['Content-Type'] = 'application/octet-stream'
	response.headers["Content-Disposition"] = "attachment; filename={}".format(articalMusic)
	#print (response.headers['Content-Type'])
	#print(response.headers["Content-Disposition"])
	#print(response.headers)
	return response

@app.route('/wordMusic/<wordMusic>',methods = [ 'GET'])
def word_music(wordMusic):
	words = mongo.db.voca_packed

	word_index=wordMusic[0:-4]
	#print('word_index: ',word_index)


	users = mongo.db.users

	type_file=wordMusic[-3:]



	
	datas=b''
		#print('enter mp3')
	

	try:
	
		#print('word_music_filename',word_music_filename)
		word_doc = words.find_one({'word_index':int(word_index)})
		datas=word_doc.get('mp3_datas')
	except:
		pass

	




	response= Response(datas, mimetype="audio/mpeg")

	response.headers['Content-Type'] = 'application/octet-stream'
	response.headers["Content-Disposition"] = "attachment; filename={}".format(wordMusic)
	#print (response.headers['Content-Type'])
	#print(response.headers["Content-Disposition"])
	#print(response.headers)
	return response





		


@app.route('/wordJpg/<wordMusic>',methods = [ 'GET'])
def word_jpg(wordMusic):
	words = mongo.db.voca_packed

	word_index=wordMusic[0:-6]
	#print('word_index: ',word_index)


	users = mongo.db.users

	flag=wordMusic[-5:-4]



	
	datas=b''
		#print('enter mp3')
	

	try:
	
		#print('word_music_filename',word_music_filename)
		word_doc = words.find_one({'word_index':int(word_index)})
		jpg_req=('jpg_'+flag+'_datas')
		#print(jpg_req)
		datas=word_doc.get(jpg_req)
	except:
		pass

	




	response= Response(datas, mimetype="audio/mpeg")

	response.headers['Content-Type'] = 'application/octet-stream'
	response.headers["Content-Disposition"] = "attachment; filename={}".format(wordMusic)
	#print (response.headers['Content-Type'])
	#print(response.headers["Content-Disposition"])
	#print(response.headers)
	return response












@app.route('/search',methods = ['POST'])
def search():
	users = mongo.db.users
	words = mongo.db.voca_packed




	try:

		searchtxt = request.form['searchtxt']
		searchtxt=searchtxt.strip()

		#print("searchtxt:",searchtxt)

		word_doc=words.find_one({'word':searchtxt})
		##print('worddata:',worddata)

		word_index=str(word_doc.get('word_index'))
		#session['user_level']=word_index

		word=word_doc.get('word')
		word_tip=word_doc.get('word_tip')
		word_def=word_doc.get('word_def')
		wordMusic="/wordMusic/"+word_index+".mp3"
	 
		image_a="/wordJpg/"+word_index+"-a.jpg"
		image_b="/wordJpg/"+word_index+"-b.jpg"
		clipart_c="/wordJpg/"+word_index+"-c.jpg"
		clipart_d="/wordJpg/"+word_index+"-d.jpg"

		res={'result':True,'user_level':str(word_index),'word':word,'word_tip':word_tip,'word_def':word_def,
		'wordMusic':wordMusic,'image_a':image_a,'image_b':image_b,
		'clipart_c':clipart_c,'clipart_d':clipart_d}

		
		
	except:
		res={'result':False}
		

	return json.dumps(res)	



@app.route('/explode_mode/', methods = [ 'POST'])
def explode_mode():
	##users = mongo.db.users
	words = mongo.db.voca_packed
	##user_posts=mongo.db.user_posts

	##username=session['username']
	##print("username:",username)

	word_index=request.form['word_index']
	input_text=""
	try:
		word_doc = words.find_one({'word_index':int(word_index)})
		word=word_doc.get('word')
		
		word_tip=word_doc.get('word_tip')
		input_text=input_text+word_tip+'. '

		word_def=word_doc.get('word_def')
		input_text=input_text+word_def


	except:
		word_tip="no defines"
		word_def="no defines"


	say=Sentence(input_text)
	say.sent_token()
	input_text=say.get('sent_token')
	#print('input_text:',input_text)

	sentence_list=[]
	#sentence_mp3_list=[]
	my={}
	for sentence in input_text:
		try:
			my['sentence']=sentence
			#my['sentence_mp3']=tts_mp3(sentence)
			#my['sentence_mp3']=b''
			sentence_list.append(my)
			my={}
		except:
			pass

	grade_list=say.grade_text()

	grade_list.sort()
	#print(grade_list[-15:])
	grade_list = list(set(grade_list))


	
	grade_list=[w for w in grade_list if not w ==0]
	grade_list.sort()

	#print(grade_list)
	if len(grade_list)>24:
		grade_list =[w for w in grade_list[-12:] ]
	else:
		grade_list=	[w for w in grade_list[-6:] ]

	#print(grade_list)
	grade_list.reverse()
	res={'grade_list':grade_list}
	#print('res:',res)
	res_json=json.dumps(res)
	return res_json

@app.route('/lemmas/stem/<word_index>', methods = [ 'GET'])
def stem(word_index):
	##users = mongo.db.users
	words = mongo.db.voca_packed
	##word_index =request.form['word_index']
	try:
		word_doc = words.find_one({'word_index':int(word_index)})
		word=word_doc.get('word')
		print('word found: ',word)
		res={'stem':PorterStemmer().stem(word)}
	except:
		res={'stem':'be'}


	res_json=json.dumps(res)
	return res_json

@app.route('/synonyms/', methods = [ 'POST'])
def get_synonyms():

	users = mongo.db.users
	words = mongo.db.voca_packed
	##user_posts=mongo.db.user_posts

	##username=session['username']
	##print("username:",username)

	word_index=int(request.form['word_index'])
	#print('word_index:',word_index)
	synonyms=[]
	try:
		word_doc = words.find_one({'word_index':word_index})
		word=word_doc.get('word')
  
		syns = wordnet.synsets(word) 
		#print ('syns:',syns)
		for item in syns:
			syn=item.lemmas()[0].name()
			#print(syn)
			try:
				syn_doc = words.find_one({'word':syn})
				
				syn_index= syn_doc.get('word_index')
				if ( syn_index not in synonyms) and ( not(syn_index==word_index)):
					synonyms.append(syn_index)
				else:
					pass
			except:
				pass

			
			

	except:
		pass  
	# An example of a synset: 
	#print(syns[0].name()) 
	  
	# Just the word: 
	#print(syns[0].lemmas()[0].name()) 
	res ={'synonyms':synonyms}
	#print(res)
	res_json=json.dumps(res)
	return res_json
	


@app.route('/testmode',methods = [ 'GET'])
def testmode():

	#print('user: ',session['username'])


	return render_template('testmode.html'
		)


@app.route('/help',methods = ['POST', 'GET'])
def help():
	return render_template('help.html')

if __name__ == '__main__':
	app.secret_key = 'mysecret'
	app.run(host='0.0.0.0',port=5000,debug=False)